<template>
  <div class="i-form">
    <el-form
      :ref="setItemRef"
      :model="model"
      :rules="rules"
      :inline="inline"
      :label-width="labelWidth"
      :label-position="labelPosition"
      :style="formStyle"
    >
    <slot name="header"></slot>
    <el-form-item
        v-for="(item , index) in elem"
        :key="index"
        :prop="item.prop"
        :label="item.label"
        :label-width="item.labelWidth"
        :style="item.style"
      >
      <slot name="formTop"></slot>
        <!-- 输入框 -->
        <el-input
          v-if="!item.element"
          clearable
          :type="item.type"
          v-model="model[item.prop]"
          :placeholder="item.placeholder??`请输入${item.label}`"
          :size="item.size??'default'"
          :disabled="item.disabled"
          :readonly="item.readonly"
          :icon="item.icon"
          :suffix="item.suffix"
          :number="item.number"
          :rows="item.rows"
          :autosize="item.autosize"
          :style="item.elemStyle"
          :show-password="item.showPassword"
        />
        <!-- 数字输入框 -->
        <el-input-number
          v-if="item.element === 'number'"
          :max="item.max"
          :min="item.min??0"
          v-model="model[item.prop]"
          :placeholder="item.placeholder??`请输入${item.label}`"
          :size="item.size??'default'"
          :disabled="item.disabled"
          :style="item.elemStyle"
        />
        <!-- 下拉框选择器 -->
        <el-select
        v-if="item.element === 'select'"
        clearable
        v-model="model[item.prop]"
        :placeholder="item.placeholder??`请选择${item.label}`"
        :size="item.size??'default'"
        :disabled="item.disabled"
        :filterable="item.filterable"
        :multiple="item.multiple"
        :style="item.elemStyle"
        @on-change="(value) => $emit(`on-${item.events}`, value)"
      >
        <el-option
          v-for="(opt, index) in item.option"
          :key="index"
          :label="opt[item.optlabel?item.optlabel:'label']"
          :value="opt[item.optvalue?item.optvalue:'value']"
          :disabled="opt.disabled"
          >{{ opt[item.optlabel?item.optlabel:'label'] }}</el-option
        >
        </el-select>
        <span v-if="item.element === 'select'&&item.remark" :style="{color:'rgb(140, 140, 140)',paddingBottom:'10px'}">{{item.remark}}</span>
        <!-- 级联选择 -->
        <el-cascader
          v-if="item.element === 'cascader'"
          :data="item.data"
          :placeholder="item.placeholder??`请输入${item.label}`"
          v-model="model[item.prop]"
          :disabled="item.disabled"
          :filterable="item.filterable"
        />
        <!-- 日期选择器 -->
        <el-date-picker
          v-if="item.element === 'date'"
          clearable
          :type="item.type"
          v-model="model[item.prop]"
          :format="item.format"
          :value-format="item.format"
          :placeholder="item.placeholder??`请输入${item.label}`"
          :size="item.size??'default'"
          :disabled="item.disabled"
          :disabled-date="item.disabledDate"
          :style="item.elemStyle"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
        />
        <!-- 时间选择器 -->
        <el-time-picker
          v-if="item.element === 'time'"
          clearable
          :type="item.type"
          v-model="model[item.prop]"
          :format="item.format"
          :placeholder="item.placeholder??`请输入${item.label}`"
          :size="item.size??'default'"
          :disabled="item.disabled"
          :style="item.elemStyle"
        />
        <!-- 单选框 -->
        <el-radio-group
          v-if="item.element === 'radio'"
          v-model="model[item.prop]"
          :label="item.label"
          :disabled="item.disabled"
          :size="item.size??'default'"
        >
        <el-radio
            v-if="!item.type || item.type!=='button'"
            v-for="(opt, index) in item.option"
            :key="index"
            :label="opt.value"
            :size="item.size??'default'"
            :fill="item.fill"
            >{{ opt.label }}</el-radio>
        <el-radio-button
          v-if="item.type=='button'"
          v-for="(opt, index) in item.option"
          :key="index"
          :label="opt.value"
          :size="item.size??'default'"
          :fill="item.fill"
          >{{ opt.label }}</el-radio-button>
        </el-radio-group>
        <!-- 多选框 -->
        <el-checkbox
          v-if="item.element === 'checkbox'"
          v-model="model[item.prop]"
          :label="item.value"
          :size="item.size??'default'"
          :disabled="item.disabled"
          />
          <!-- 开关 -->
          <el-switch
            v-if="item.element === 'switch'"
            v-model="model[item.prop]"
            class="ml-2"
            :size="item.size??'default'"
            :disabled="item.disabled"
            :active-icon="item.onIcon"
            :inactive-icon="item.offIcon"
            :active-text="item.onText"
            :inactive-text="item.offText"
            :active-value="item.activeValue"
            :inactive-value="item.inactiveValue"
          />
        <!-- 文本状态 -->
        <span v-if="item.element === 'text'" :style="item.switchStyle">{{ item.textType }}</span>
        </el-form-item>
      <slot name="formBottom"></slot>
    <!-- 按钮 -->
    <el-form-item :style="Object.assign(btnStyle,{paddingLeft: '20px'})" class="formBtn">
        <el-button
          v-if="submit"
          :type="okType"
          :size="btnSize"
          :icon="okIcon"
          :long="btnLong"
          :loading="btnLoading"
          @click="handleSubmit('form')"
        >
          {{ submitText }}
        </el-button>
        <el-button
          v-if="button"
          :type="btnType2"
          :size="btnSize"
          :icon="btnIcon2"
          :long="btnLong2"
          @click="handleClick"
          class="button"
          >{{ buttonText }}</el-button>
        <el-button
          v-if="reset"
          :type="btnType"
          :size="btnSize"
          :icon="btnIcon"
          :long="btnLong"
          @click="handleReset()"
          class="button"
          >{{ resetText }}</el-button>
        <slot name="footer"></slot>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang='ts'>
import { reactive, ref } from 'vue';
const emit = defineEmits(['onSuccess', 'onReset', 'onClick'])
const state = reactive({});
const ruleFormRef = ref()
const setItemRef = el => {
    if (el) {
      ruleFormRef.value = el
    }
}
const props = defineProps({
  // ref
  formRef:{
    type:String,
    default:'ruleFormRef'
  },
  // 表单对象
  model:{
    type:Object as any
  },
  // 规则验证
  rules: Object,
  // 是否为行内表单
  inline:{
    type:Boolean,
    default:true
  },
  // 表单域标签宽度
  labelWidth:{
    type:String,
    default:'80px'
  },
  // 表单域标签位置
  labelPosition: {
    validator(value) {
      const validList = ["left", "right", "top"];
      for (let i = 0; i < validList.length; i++) {
        if (value === validList[i]) {
          return true;
        }
      }
      return false;
    },
    default: "right",
  },
  // 自定义样式
  formStyle:{
    type:Object,
    default:{ width:'100%' }
  },
  // 自定义表单
  elem: { type: Array as any, default: [] },
  // 表单加载状态
  loading: {
    type: Boolean,
    default: false,
  },
  // 是否显示提交按钮
  submit: {
    type: Boolean,
    default: false,
  },
  reset: {
    type: Boolean,
    default: false,
  }, // 是否显示重置按钮
  button: {
    type: Boolean,
    default: true,
  }, // 是否显示普通按钮
  submitText: {
    type: String,
    default: "搜索",
  }, // 提交按钮文字
  resetText: {
    type: String,
    default: "重置",
  }, // 重置按钮文字
  buttonText: {
    type: String,
    default: "Button",
  }, // 普通按钮文字
  okType: {
    type: String,
    default: "primary",
  }, // 提交按钮类型
  btnType: String, // 普通按钮类型
  btnLong: Boolean, // 设置按钮的长度为 100%
  // 设置按钮的图标类型
  okIcon: String,
  btnIcon: String,
  btnLoading: {
    type: Boolean,
    default: false,
  }, // 按钮加载状态
  btnType2: {
    type: String,
    default: "primary",
  }, // 普通按钮类型
  btnSize: {
    type: String,
    default: "small",
  }, // 普通按钮类型
  btnLong2: Boolean, // 设置按钮的长度为 100%
  // 设置按钮的图标类型
  btnIcon2: String,
  btnStyle:{
    type:Object,
    default:{ }
  },
})
const handleSubmit = (ref?:string) => {
  let flag = validate()
  if (!flag) {
        return
  }
  emit("onSuccess",props.model);
}
const handleReset = () => {
  ruleFormRef.value.resetFields()
  emit("onReset");
}
const handleClick = () => {
  emit("onClick");
}
const validate = async() => {
  return new Promise((resolve, reject)=>{
    ruleFormRef.value.validate((valid) => {
      resolve(valid)
    });
  })
}
const concel = () => {
  ruleFormRef.value.resetFields()
}
defineExpose({
  validate,
  concel
})
</script>

<style lang='scss' scoped>
.i-form{
  width: 100%;
  :deep(.el-form){
    width: 100%;
    height: 100%;
    // display: flex;
    // flex-wrap: wrap;
    // align-items: center;
    padding-bottom: 20px;
    &>.el-form-item{
      margin: 0;
    }
  }
}
</style>
